﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;

namespace KduneeShaders.PostProcess
{
    /// <summary>
    /// Ogólna klasa shadera służącego do tworzenia efektów post-process
    /// </summary>
    abstract public class PostProcessShader
    {
        protected Effect effect;
        private SpriteBatch postSpriteBatch;
        private RenderTarget2D postRenderTarget;
        private RenderTargetBinding[] temp;

        /// <summary>
        /// Przygotuj shader do działania
        /// </summary>
        /// <param name="graphics">Menadżer wyświetlania</param>
        /// <param name="content">Menadżer danych</param>
        public virtual void Prepare(GraphicsDeviceManager graphics, ContentManager content)
        {
            postRenderTarget = new RenderTarget2D(graphics.GraphicsDevice,
                graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height,
                false, graphics.GraphicsDevice.DisplayMode.Format, DepthFormat.Depth24);

            postSpriteBatch = new SpriteBatch(graphics.GraphicsDevice);
        }

        /// <summary>
        /// Wykonaj operacje niezbędne przed renderingiem sceny
        /// </summary>
        /// <param name="graphics">Menadżer wyświetlania</param>
        public virtual void PreRender(GraphicsDeviceManager graphics)
        {
            temp = graphics.GraphicsDevice.GetRenderTargets();
            graphics.GraphicsDevice.SetRenderTarget(postRenderTarget);
            graphics.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
        }

        /// <summary>
        /// Wykonaj operacje niezbędne po renderingu sceny
        /// </summary>
        /// <param name="graphics">Menadżer wyświetlania</param>
        public virtual void PostRender(GraphicsDeviceManager graphics)
        {
            graphics.GraphicsDevice.SetRenderTargets(temp);

            postSpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                postSpriteBatch.Draw(postRenderTarget, Vector2.Zero, Color.White);
            }

            postSpriteBatch.End();
        }
    }
}
